
#ifndef _MATRIX_H_
#define _MATRIX_H_

#include <vector>
#include <iostream>

typedef double MatrixElement; // тип элементов матрицы, чтобы не делать шаблоны
const int IndexOffset = 1; // откуда начинаются индексы матрицы, IndexOffset==1 означает, что индексы начинаются с единицы
const double AllowedEps = 1e-7; // значения меньше этого числа при вывод считать нулем

class SquareMatrix {
public:
	SquareMatrix(int dimension);
	SquareMatrix(const SquareMatrix &other);
	SquareMatrix &operator=(const SquareMatrix &other);

	static SquareMatrix identity(int dimension); // единичная матрица заданной размерности

	MatrixElement &operator()(int row, int col); // обращение к элементам

	// алгебра
	SquareMatrix operator+(const SquareMatrix &other);  // сложение матриц
	SquareMatrix operator-(const SquareMatrix &other);  // вычитание матриц
	SquareMatrix operator*(MatrixElement factor); // умножение матрицы на число
	std::vector<MatrixElement> operator*(const std::vector<MatrixElement> &vec); // умножение матрицы на вектор
	SquareMatrix operator*(const SquareMatrix &other);  // перемножение матриц

	// получить размерность
	int getDimension() const;

private:
	int _dimension; // размерность матрицы
	std::vector<MatrixElement> _matrix; // плоская для экономии памяти

	// друзья
	friend std::ostream &operator<<(std::ostream &, SquareMatrix &);
	friend std::istream &operator>>(std::istream &, SquareMatrix &);
};

// умножение числа на матрицу
SquareMatrix operator*(MatrixElement, SquareMatrix &);
// ввод-вывод
std::ostream &operator<<(std::ostream &, SquareMatrix &);
std::istream &operator>>(std::istream &, SquareMatrix &);

#endif
